﻿/*----------------------------------------------------------------
// Copyright (C) 2023 版权所有。 
//
// 文件功能描述：   Stacking控制界面，该窗口用于测试使用
// 文件创建者：     王志国
// 时间：           2023 年 7 月 12 日
// 
// 修改履历：
// 时间         作者       修改内容                   修改原因
// 2023/7/12   王志国      新建
//----------------------------------------------------------------*/
using Goway.Log4net;
using Goway.StackingUC.Entities.DataDefinition;
using Goway.StackingUC.Entities;
using Goway.StackingUC.Services;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SqlSugar;
using Goway.Stacking.StackingControl;

namespace Goway.StackingUC
{
    public partial class FrmStackingMain : UIForm
    {
        /// <summary>
        /// Stacking IP，测试暂定为静态
        /// </summary>
        private string Stacking_IP = "192.168.0.254";

        /// <summary>
        /// 堆垛机控制器
        /// </summary>
        private StackingControllerTest stackingCtrl;

        /// <summary>
        /// 业务类型
        /// </summary>
        private BizType bizType;

        /// <summary>
        /// 取货坐标
        /// </summary>
        private short[,] fromCoordinate;

        /// <summary>
        /// 放货坐标
        /// </summary>
        private short[,] toCoordinate;

        public FrmStackingMain()
        {
            InitializeComponent();

            string plcIP = this.txtStackingIP.Text;
            if (string.IsNullOrEmpty(plcIP))
            {
                plcIP = Stacking_IP;
            }

            // 需验证 IP 格式是否合法
            stackingCtrl = new StackingControllerTest(plcIP);

            // 默认业务类型（测试使用，实际中都是事件触发）
            this.bizType = BizType.InputStorage;
        }

        #region 连接和断开

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConn_Click(object sender, EventArgs e)
        {
            if (this.stackingCtrl == null)
            {
                this.ShowMessage("系统错误，对象为空");
                return;
            }

            if (!stackingCtrl.Connect(out string msg))
            {
                this.ShowMessage(msg);
                return;
            }

            btnConn.Enabled = false;
            btnDisConn.Enabled = true;
            this.ShowMessage("连接堆垛机成功");
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDisConn_Click(object sender, EventArgs e)
        {
            if (stackingCtrl != null)
            {
                if (!stackingCtrl.DisConnect(out string msg))
                {
                    this.ShowMessage(msg);
                    return;
                }

                this.ShowMessage("断开堆垛机成功！");

                btnConn.Enabled = true;
                btnDisConn.Enabled = false;

                return;
            }

            this.ShowMessage("断开堆垛机，发生系统错误");
        }

        #endregion

        #region 运行

        /// <summary>
        /// 手动运行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnManualRun_Click(object sender, EventArgs e)
        {
            if (this.stackingCtrl == null)
            {
                this.ShowMessage("系统错误，对象为空");
                return;
            }

            string errorMsg = "";

            try
            {
                if (this.bizType != BizType.InputStorage)                  // 入库不需要取料地址
                {
                    // 检查取料地址坐标
                    if (!GetFromCoord())
                    {
                        ShowMessage("请修改取料坐标值后，再进行手动运行操作！");
                        return;
                    }

                    if (!stackingCtrl.SetCoordinate(this.fromCoordinate, 0, out errorMsg))
                    {
                        this.ShowMessage(errorMsg);
                        return;
                    }
                }

                if (this.bizType != BizType.OutputStorage)                 // 出库不需要放料地址
                {
                    // 检查放料地址坐标
                    if (!GetToCoord())
                    {
                        ShowMessage("请修改放料坐标值后，再进行手动运行操作！");
                        return;
                    }

                    if (!stackingCtrl.SetCoordinate(this.toCoordinate, 1, out errorMsg))
                    {
                        this.ShowMessage(errorMsg);
                        return;
                    }
                }

                // 任务下发标记
                if (!stackingCtrl.SendTaskOrder(this.bizType, out errorMsg))
                {
                    this.ShowMessage(errorMsg);
                    return;
                }

                this.ShowMessage("任务完成！");
            }
            catch (Exception ex)
            {
                this.ShowMessage($"发生异常：{ex.Message}");
            }
        }

        /// <summary>
        /// 自动运行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAutoRun_Click(object sender, EventArgs e)
        {
            string errorMsg = "";

            try
            {
                switch (this.bizType)
                {
                    case BizType.Unknown:
                        this.ShowMessage("请选择业务类型后进行自动运行操作。");
                        return;

                    case BizType.InputStorage:
                        // 设置放料地址，可零放/整放，可主档区/临时区
                        if (!stackingCtrl.SetToCoordinate(this.bizType, ColumnAreaType.TempArea, out errorMsg))
                        {
                            this.ShowMessage($"设置放料坐标错误：{errorMsg}");
                            return;
                        }
                        break;

                    case BizType.OutputStorage:
                        // 设置取料地址，整取，可主档区/临时区
                        if (!stackingCtrl.SetFromCoordinate(this.bizType, ColumnAreaType.MainArea, out errorMsg, true))
                        {
                            this.ShowMessage($"设置取料坐标错误：{errorMsg}");
                            return;
                        }
                        break;

                    case BizType.ShiftingStorage:
                        // 设置取料地址，整取  可主档区/临时区
                        if (!stackingCtrl.SetFromCoordinate(this.bizType, ColumnAreaType.MainArea, out errorMsg, true))
                        {
                            this.ShowMessage($"设置取料坐标错误：{errorMsg}");
                            return;
                        }

                        // 设置放料地址，整放  位置与取料相反
                        if (!stackingCtrl.SetToCoordinate(this.bizType, ColumnAreaType.TempArea, out errorMsg))
                        {
                            this.ShowMessage($"设置放料坐标错误：{errorMsg}");
                            return;
                        }

                        break;

                    default:
                        this.ShowMessage("请选择业务类型后进行自动运行操作。");
                        return;
                }

                // 任务下发标记
                if (!stackingCtrl.SendTaskOrder(this.bizType, out errorMsg))
                {
                    this.ShowMessage(errorMsg);
                    return;
                }
            }
            catch (Exception ex)
            {
                this.ShowMessage($"执行任务发生异常：{ex.Message}");
                return;
            }
        }

        #endregion

        #region 业务选择事件

        private void rdoInputStorage_CheckedChanged(object sender, EventArgs e)
        {
            this.bizType = BizType.InputStorage;

            lblOutputWarning.Visible = false;
        }

        private void rdoOutputStorage_CheckedChanged(object sender, EventArgs e)
        {
            this.bizType = BizType.OutputStorage;
            lblOutputWarning.Visible = true;
        }

        private void rdoRotateStorage_CheckedChanged(object sender, EventArgs e)
        {
            this.bizType = BizType.ShiftingStorage;
            lblOutputWarning.Visible = false;
        }

        #endregion

        #region 工具

        /// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="msg"></param>
        public void ShowMessage(string msg)
        {
            if (!this.Created)
            {
                return;
            }

            if (this.txtMessage.InvokeRequired && !txtMessage.IsDisposed)
            {
                this.Invoke(new MethodInvoker(delegate
                {
                    this.txtMessage.Text = this.txtMessage.Text.Insert(0, DateTime.Now.ToString("t") + " : " + msg + "\n");
                }));
            }
            else if (!txtMessage.IsDisposed)
            {
                this.txtMessage.Text = this.txtMessage.Text.Insert(0, DateTime.Now.ToString("t") + " : " + msg + "\n");
            }
        }

        /// <summary>
        /// 验证输入的值  该函数可以显示错误信息
        /// </summary>
        /// <returns></returns>
        private bool CheckInputToCoord()
        {
            short lastValue = 0;                      // 记录刚验证过的数据

            bool isWholePackage = false;              // 是否整放
            if (this.bizType != BizType.InputStorage)
            {
                isWholePackage = true;
            }

            #region 排验证

            if (txtCoord11.Text == "" || !short.TryParse(txtCoord11.Text, out short txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_ROW_COUNT)
            {
                this.ShowMessage($"坐标（1,1）错误");
                return false;
            }

            lastValue = txtValue;
            if (txtCoord21.Text == "" || !short.TryParse(txtCoord21.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_ROW_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（2,1）错误");
                return false;
            }

            if (txtCoord31.Text == "" || !short.TryParse(txtCoord31.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_ROW_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（3,1）错误");
                return false;
            }

            if (txtCoord41.Text == "" || !short.TryParse(txtCoord41.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_ROW_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（4,1）错误");
                return false;
            }

            if (txtCoord51.Text == "" || !short.TryParse(txtCoord51.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_ROW_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（5,1）错误");
                return false;
            }

            if (txtCoord61.Text == "" || !short.TryParse(txtCoord61.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_ROW_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（6,1）错误");
                return false;
            }

            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 7 && (txtCoord71.Text == "" ||
                !short.TryParse(txtCoord71.Text, out txtValue) || txtValue <= 0 ||
                txtValue > StackingControllerTest.STORE_ROW_COUNT || (isWholePackage && txtValue != lastValue)))
            {
                this.ShowMessage($"坐标（7,1）错误");
                return false;
            }

            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 8 && (txtCoord81.Text == "" ||
                txtValue > StackingControllerTest.STORE_ROW_COUNT || (isWholePackage && txtValue != lastValue)))
            {
                this.ShowMessage($"坐标（8,1）错误");
                return false;
            }

            #endregion

            #region 列验证

            if (txtCoord12.Text == "" || !short.TryParse(txtCoord12.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT)
            {
                this.ShowMessage($"坐标（1,2）错误");
                return false;
            }

            lastValue = txtValue;

            if (txtCoord22.Text == "" || !short.TryParse(txtCoord22.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（2,2）错误");
                return false;
            }

            if (txtCoord32.Text == "" || !short.TryParse(txtCoord32.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（3,2）错误");
                return false;
            }

            if (txtCoord42.Text == "" || !short.TryParse(txtCoord42.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（4,2）错误");
                return false;
            }

            if (txtCoord52.Text == "" || !short.TryParse(txtCoord52.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（5,2）错误");
                return false;
            }

            if (txtCoord62.Text == "" || !short.TryParse(txtCoord62.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT ||
                (isWholePackage && txtValue != lastValue))
            {
                this.ShowMessage($"坐标（6,2）错误");
                return false;
            }

            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 7 && (txtCoord72.Text == "" ||
                !short.TryParse(txtCoord72.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT ||
                (isWholePackage && txtValue != lastValue)))
            {
                this.ShowMessage($"坐标（7,2）错误");
                return false;
            }

            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 7 && (txtCoord82.Text == "" ||
                !short.TryParse(txtCoord82.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue)))
            {
                this.ShowMessage($"坐标（8,2）错误");
                return false;
            }

            #endregion

            #region 层验证

            if (txtCoord13.Text == "" || !short.TryParse(txtCoord13.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT)
            {
                this.ShowMessage($"坐标（1,3）错误");
                return false;
            }

            lastValue = txtValue;
            if (txtCoord23.Text == "" || !short.TryParse(txtCoord23.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue + 1))
            {
                this.ShowMessage($"坐标（2,3）错误");
                return false;
            }

            lastValue = txtValue;
            if (txtCoord33.Text == "" || !short.TryParse(txtCoord33.Text, out txtValue) ||
               txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue + 1))
            {
                this.ShowMessage($"坐标（3,3）错误");
                return false;
            }

            lastValue = txtValue;
            if (txtCoord43.Text == "" || !short.TryParse(txtCoord43.Text, out txtValue) ||
               txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue + 1))
            {
                this.ShowMessage($"坐标（4,3）错误");
                return false;
            }

            lastValue = txtValue;
            if (txtCoord53.Text == "" || !short.TryParse(txtCoord53.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue + 1))
            {
                this.ShowMessage($"坐标（5,3）错误");
                return false;
            }


            lastValue = txtValue;
            if (txtCoord63.Text == "" || !short.TryParse(txtCoord63.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue + 1))
            {
                this.ShowMessage($"坐标（6,3）错误");
                return false;
            }

            lastValue = txtValue;
            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 7 && (txtCoord73.Text == "" ||
                !short.TryParse(txtCoord73.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue + 1)))
            {
                this.ShowMessage($"坐标（7,3）错误");
                return false;
            }

            lastValue = txtValue;
            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 8 && (txtCoord83.Text == "" ||
                !short.TryParse(txtCoord83.Text, out txtValue)
                || txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT ||
                (isWholePackage && txtValue != lastValue + 1)))
            {
                this.ShowMessage($"坐标（8,3）错误");
                return false;
            }

            #endregion

            return true;
        }

        /// <summary>
        /// 验证输入的取料地址坐标的合法性
        /// </summary>
        /// <returns>是否合法的结果值</returns>
        private bool CheckInputFromCoord()
        {
            if (txtSrcCoordRow.Text == "" || !short.TryParse(txtSrcCoordRow.Text, out short txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_ROW_COUNT)
            {
                this.ShowMessage($"取料地址的排坐标错误");
                return false;
            }

            if (txtSrcCoordCol.Text == "" || !short.TryParse(txtSrcCoordCol.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_COLUMN_COUNT)
            {
                this.ShowMessage($"取料地址的列坐标错误");
                return false;
            }

            if (txtSrcCoordLev.Text == "" || !short.TryParse(txtSrcCoordLev.Text, out txtValue) ||
                txtValue <= 0 || txtValue > StackingControllerTest.STORE_LEVEL_COUNT + 1)
            {
                this.ShowMessage($"取料地址的层坐标错误");
                return false;
            }

            return true;
        }

        /// <summary>
        /// 获取取货坐标
        /// </summary>
        /// <returns></returns>
        private bool GetFromCoord()
        {
            if (!CheckInputFromCoord())
            {
                return false;
            }

            fromCoordinate = new short[StackingControllerTest.COORDINATE_ROW_COUNT, StackingControllerTest.COORDINATE_COLUMN_COUNT];

            if (!short.TryParse(txtSrcCoordRow.Text, out short rowCoord) ||
                !short.TryParse(txtSrcCoordCol.Text, out short colCoord) ||
                !short.TryParse(txtSrcCoordLev.Text, out short levCoord))
            {
                return false;
            }

            for (int i = 0; i < StackingControllerTest.COORDINATE_ROW_COUNT; i++)
            {
                this.fromCoordinate[i, 0] = rowCoord;
                this.fromCoordinate[i, 1] = colCoord;
                this.fromCoordinate[i, 2] = levCoord++;
            }

            return true;
        }

        /// <summary>
        /// 获取取货坐标
        /// </summary>
        /// <returns></returns>
        private bool GetToCoord()
        {
            if (!CheckInputToCoord())
            {
                return false;
            }

            toCoordinate = new short[StackingControllerTest.COORDINATE_ROW_COUNT, StackingControllerTest.COORDINATE_COLUMN_COUNT];

            this.toCoordinate[0, 0] = short.Parse(txtCoord11.Text);
            this.toCoordinate[0, 1] = short.Parse(txtCoord12.Text);
            this.toCoordinate[0, 2] = short.Parse(txtCoord13.Text);

            this.toCoordinate[1, 0] = short.Parse(txtCoord21.Text);
            this.toCoordinate[1, 1] = short.Parse(txtCoord22.Text);
            this.toCoordinate[1, 2] = short.Parse(txtCoord23.Text);

            this.toCoordinate[2, 0] = short.Parse(txtCoord31.Text);
            this.toCoordinate[2, 1] = short.Parse(txtCoord32.Text);
            this.toCoordinate[2, 2] = short.Parse(txtCoord33.Text);

            this.toCoordinate[3, 0] = short.Parse(txtCoord41.Text);
            this.toCoordinate[3, 1] = short.Parse(txtCoord42.Text);
            this.toCoordinate[3, 2] = short.Parse(txtCoord43.Text);

            this.toCoordinate[4, 0] = short.Parse(txtCoord51.Text);
            this.toCoordinate[4, 1] = short.Parse(txtCoord52.Text);
            this.toCoordinate[4, 2] = short.Parse(txtCoord53.Text);

            this.toCoordinate[5, 0] = short.Parse(txtCoord61.Text);
            this.toCoordinate[5, 1] = short.Parse(txtCoord62.Text);
            this.toCoordinate[5, 2] = short.Parse(txtCoord63.Text);

            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 7)
            {
                this.toCoordinate[6, 0] = short.Parse(txtCoord71.Text);
                this.toCoordinate[6, 1] = short.Parse(txtCoord72.Text);
                this.toCoordinate[6, 2] = short.Parse(txtCoord73.Text);
            }

            if (StackingControllerTest.MATERIAL_COUNT_PEER_PACKAGE >= 8)
            {
                this.toCoordinate[7, 0] = short.Parse(txtCoord81.Text);
                this.toCoordinate[7, 1] = short.Parse(txtCoord82.Text);
                this.toCoordinate[7, 2] = short.Parse(txtCoord83.Text);
            }

            return true;
        }

        #endregion

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
